<script lang="jsx" setup>
import {
  Delete,
  Plus,
  Search
} from '@element-plus/icons-vue'
import { ref, onMounted } from 'vue'


/* 定义属性 */
const props = defineProps({
  selectData: Function,
  deleteData: Function,
  searchData: Function,
  columns: Array,
  searchTitle: String,
  createTitle: String,
  searchPair: Object,
  append: Object
});

/* 定义事件 */
const emit = defineEmits(['click-create'], ['confirm-create'])

/* 获取列表数据，渲染表格 */
const loading = ref(true);
const dataList = ref([])

let lastMaxId = 0; // 记录当前列表中的最大 id
const getData = async () => {
  loading.value = true;
  props.selectData(lastMaxId).
  then(res => {
      const newData = res.data.data;
      for (const data of newData) {
        for (const [key, value] of Object.entries(data)) {
          if (value == null) {
            data[key] = '';
          } else if (Number.isInteger(value)) {
            data[key] = value.toString();
          }
        }
      }
      dataList.value.push(...res.data.data);
      lastMaxId = dataList.value[dataList.value.length - 1].id;
    
  })
  .catch(() => {
  }) 
  loading.value = false;
}
getData()

/* 处理append */
const append = ref(props.append ? props.append : []);
for (let i = 0; i < append.value.length; i++) {
  const obj = append.value[i];
  obj["visible"] = false;
}

/* 无限滚动 */
const tableRef = ref(null);
let timer = null;

let lastScrollTop = 0;
let scrollWrap, scrollWrapF, scrollWrapFF;
onMounted(() => {
  scrollWrap = tableRef.value.$el.querySelector('.el-vl__wrapper');
  scrollWrapF = scrollWrap.firstChild;
  scrollWrapFF = scrollWrapF.firstChild;
})

const onScroll = ({scrollTop}) => {
  // 防抖处理
  if (timer) clearTimeout(timer);
  if (loading.value) return;
  if (!scrollWrap) return;

  const clientHeight = scrollWrapF.clientHeight;
  const scrollHeight = scrollWrapFF.scrollHeight;

  timer = setTimeout(() => {
    // 判断滚动方向，只有向下滚动时才可能触发加载更多
    if (scrollTop > lastScrollTop && scrollTop + clientHeight >= scrollHeight - 100) {
      lastScrollTop = scrollTop;
      getData();
    }
  }, 500);
};

/* 搜索 */
const searchVisible = ref(false);
const serachFormModel = ref({
  searchKey: '',
  text: ''
})

const onSearch = async() => {
  const res = await props.searchData(serachFormModel.value);
  dataList.value = res.data.data;
  searchVisible.value = false;
}

/* 点击创建按钮 */
const onClickCreate = () => {
  emit('click-create');
  createVisible.value = true;
}

/* 点击确认创建按钮 */
const onConfirmCreate = () => {
  emit('confirm-create');
  createVisible.value = false;
}

/* 创建 */
const createVisible = ref(false);


/* 删除 */
const onDelete = async (rowId, rowIndex) => {
  await props.deleteData(rowId);
  dataList.value.splice(rowIndex, 1);
}
for (const column of props.columns) {
  if (column["isCopy"]) {
    column["cellRenderer"] = ({rowData}) => {
      let data = rowData[column["dataKey"]];
      return ( 
        <el-tooltip content={data} placement="bottom-end">
          {
            <span style={{ overflow: 'hidden', textOverflow: 'ellipsis' }}>{data}</span>
          } 
        </el-tooltip>
      )
    }
  }
}
props.columns.push(  
  {
    dataKey: "op",
    title: "",
    width: 100,
    cellRenderer: ({rowData, rowIndex}) => {
      return ( 
        <el-tooltip content="删除" placement="bottom-end">
          <el-button type="danger" icon={Delete} onClick={() => onDelete(rowData["id"], rowIndex)}></el-button> 
        </el-tooltip>
      )
    }
  }
);

</script>

<template>
  <el-container style="height: 100%;">
    <slot></slot>
    <el-header style="border: 1px solid rgb(229, 229, 229); height: auto;">
      <div style="
        display: flex;
        flex-direction: row-reverse;
        align-items: center;
        overflow-x: auto;
        height: auto;
      ">
        <el-button
          v-if="createTitle"
          style="margin: 10px 0px 10px 15px;"
          @click="onClickCreate"
          :icon="Plus"
          type="default"
          color="black"
          size="large"
          auto-insert-space
        >
          <span v-text="createTitle"></span>
        </el-button>
        <el-dialog v-if="createTitle" v-model="createVisible" :title="createTitle" draggable>
          <slot name="create"></slot>
          <template #footer>
            <span class="dialog-footer">
              <el-button @click="onConfirmCreate">确认</el-button>
              <el-button type="primary" @click="createVisible = false">
                取消
              </el-button>
            </span>
          </template>
        </el-dialog>

        <el-button
          v-if="searchTitle"
          style="margin: 10px 0px 10px 15px;"
          @click="searchVisible = true"
          :icon="Search"
          type="default"
          color="black"
          size="large"
          auto-insert-space
        >
          <span v-text="searchTitle"></span>
        </el-button>
        <el-dialog v-if="searchTitle" v-model="searchVisible" :title="searchTitle" draggable>
          <el-form @submit.prevent>
            <el-input v-model="serachFormModel.text" @keyup.enter="onSearch">
              <template #prepend>
                <el-select v-model="serachFormModel.searchKey" placeholder="Select" style="width: 115px">
                  <el-option :label="key" :value="value" v-for="(value, key) in searchPair" :key="key"/>
                </el-select>
              </template>
              <template #append>
                <el-button :icon="Search" @click="onSearch" />
              </template>
            </el-input>
          </el-form>
        </el-dialog>

        <div v-for="obj in append">
          <el-button
            v-if="obj.title"
            style="margin: 10px 0px 10px 15px;"
            @click="obj.visible = true"
            :icon="Search"
            type="default"
            color="black"
            size="large"
            auto-insert-space
          >
            <span v-text="obj.title"></span>
          </el-button>
          <el-dialog v-if="obj.title" v-model="obj.visible" :title="obj.title" draggable>
            <slot :name="obj.title"></slot>
          </el-dialog>
        </div>

      </div>
    </el-header>
    <el-main style="flex: 1; border: 1px solid rgb(229, 229, 229);">
      <el-auto-resizer>
        <template #default="{ height, width }">
          <el-table-v2 ref="tableRef" v-loading="loading" :cache="6" :height="height" :width="width"
            :columns="columns" :data="dataList" @scroll="onScroll" fixed>
            <template #empty>
              <el-empty description="没有数据"></el-empty>
            </template>
          </el-table-v2>
        </template>
      </el-auto-resizer>
    </el-main>
  </el-container>
</template>

<style lang="scss" scoped>
::v-deep(.el-dialog) {
  width: 80vw;
  padding: 50px;

  @media (min-width: 768px) {
    width: 40vw;
  }

  @media (min-width: 1024px) {
    width: 25vw;
  }
}
</style>
